/*
 *      libidxp.h
 *      
 *      Copyright 2009 Daniele Ricci <denn86@gmail.com>, Luca Saccagi <luksak86@gmail.com>
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */


#ifndef _LIBIDXP
#define _LIBIDXP


//################################################ INCLUDE
#include <vortex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <assert.h>
#include <dirent.h>
#include <time.h>
#include <winf.h>
#else
#include <sys/types.h>
#include <sys/dir.h>
#endif
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/valid.h>


//################################################ DEFINE
#define PLAIN_PROFILE "http://fact.aspl.es/profiles/plain_profile" 
#define IDXP_PROFILE "http://idxp.org/beep/profile"
#define TLS_PROFILE "http://iana.org/beep/TLS"

#define MAX_STRING_SIZE 200
#define MAX_CONNECTIONS 200
#ifdef _WIN32
#define CLOSING_POLLING 100
#else
#define CLOSING_POLLING 100000
#endif
#define TIMEOUTS 10


#define INITIATOR 1
#define LISTENER 0
#define IDXPLIB_LISTENER idxp_initialization(LISTENER);
#define IDXPLIB_INITIATOR idxp_initialization(INITIATOR);

#define IDXPROLE_HC 0
#define IDXPROLE_HS 1
#define IDXPROLE_AC 2
#define IDXPROLE_AS 3
#define IDXPROLE_CC 4
#define IDXPROLE_CS 5
#define IDXPROLE_EC 6
#define IDXPROLE_ES 7


//################################################ STRUCT
typedef long int lint;
typedef const char cchar;

typedef xmlDtdPtr IdxpDtd;
typedef VortexFrame IdxpFrame;
typedef VortexConnection IdxpConnection;
typedef VortexChannel IdxpChannel;

typedef struct _srv_list{
	char ip[100];
	struct _srv_list *next;	
}srv_list;

typedef struct ext_time{
	char *hexstr;
	struct tm *t;
} extTime;

typedef struct _IdxpPeer {
	VortexChannel *ch;
	VortexConnection *cn;
	int channel_type;
	struct _IdxpPeer *next;
	struct _IdxpPeer *prev;
} IdxpPeer;

typedef struct _frame_handlers {
	bool (*heartbeat_client)();
	bool (*heartbeat_server)();
	bool (*alert_client)();
	bool (*alert_server)();
	bool (*config_client)();
	bool (*config_server)();
	bool (*extended_client)();
	bool (*extended_server)();
} frame_handlers;

typedef struct _greeting_properties {
	char uri[MAX_STRING_SIZE];
	char role[MAX_STRING_SIZE];
	char fqdn[MAX_STRING_SIZE];
	char streamt[MAX_STRING_SIZE];
}IdxpGreeting;

typedef struct _idxp_conf {
	char dtd_greeting[100];
	char dtd_idmef[100];
	char usr[100];
	char pw[100];
	char certificate[100];
	char certificate_key[100];
	char analyzer_id[100];
	char myuri[100];
	char fqdn[100];
	char srv_port[100];
	srv_list *top;
	bool loop;
	int cnt_index;
	int interval;
	struct _idxp_conf *next; //utilizzato??? comunque gestito sia dalla idxp_configuration_new sia dalla free.
	bool tls_enable;
	bool proceed_on_tls_fail;
}IdxpConfiguration;


/* 
	LIBIDXP 0.0.2 API
*/
 void idxp_initialization(int idxp_side);
 void idxp_exit(void);
//Configuration Related Functions
 IdxpConfiguration *idxp_configuration_new(void);
 void idxp_configuration_free(IdxpConfiguration *configuration);
 bool idxp_configuration_load(char *configuration_path, IdxpConfiguration *idxp_config);
 char *idxp_configuration_get(char *parm_name, IdxpConfiguration *idxp_config);
 void idxp_configuration_set(char *parm_name,char *parm_val, IdxpConfiguration *idxp_config);
//Custom frame_handlers Related Functions
 void idxp_custom_heartbeat_client_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));
 void idxp_custom_heartbeat_server_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));
 void idxp_custom_alert_client_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));
 void idxp_custom_alert_server_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));
 void idxp_custom_config_client_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));
 void idxp_custom_config_server_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));
 void idxp_custom_extended_client_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));
 void idxp_custom_extended_server_set(bool (*function)(IdxpConnection *connection,IdxpChannel *channel,IdxpFrame *frame,axlPointer user_data));


//Greeting Related Functions
 char *idxp_greeting_set(char mygreet[1000],cchar *role,cchar* uri,cchar *fqdn,cchar *stype);
 IdxpGreeting *idxp_greeting_get(char *greet);
 bool idxp_greeting_send_and_wait(IdxpChannel *channel,cchar *role,cchar *streamtype, bool explicit_call);
//DTD Related Functions
 void idxp_dtd_init(void);
 IdxpDtd idxp_dtd_load(const char *dtd);
 void idxp_dtd_free(IdxpDtd dtd);
 bool idxp_dtd_validate_frame(IdxpFrame *frame,IdxpDtd dtd,char *firstflag);
 bool idxp_dtd_validate_buffer(char *buffer,IdxpDtd dtd);
//Connection & Channel Related Functions
 void idxp_listener_wait(void);
 IdxpConnection *idxp_connection_new(IdxpConnection *connection, char *host, char *port);
 IdxpConnection *idxp_connection_start(IdxpConnection *cn,cchar *host,cchar *port,cchar *usr,cchar *pw);
 IdxpChannel *idxp_channel_new(IdxpConnection *cn,int chNum,cchar *srvName,bool set_piggyback,cchar *role,cchar *uri,cchar *fqdn,cchar *streamType);
 void idxp_channel_close(IdxpChannel *channel);
 bool idxp_channel_greeted(IdxpChannel *channel);
 int idxp_channel_get_roleid(char *stype, char *role);
 bool idxp_channel_get_bool_data(IdxpChannel *channel,char *key);
 void idxp_channel_set_bool_data(IdxpChannel *channel,char *key, bool value);
 bool idxp_connection_is_ok(IdxpConnection *connection);
//Frame & Msg related functions
 IdxpFrame *idxp_channel_send_msg_and_wait(IdxpChannel *ch,cchar *msg);
 bool idxp_channel_send_msg(VortexChannel *ch,cchar *msg);
 char *idxp_frame_get_payload(IdxpFrame *frame);
//Broadcast related functions
 IdxpPeer *idxp_broadcast_peer_create(IdxpConnection *connection, IdxpChannel *channel, int channel_type);
 IdxpPeer *idxp_broadcast_peer_headinsert(IdxpPeer *toplist, IdxpPeer *to_insert);
 IdxpPeer *idxp_broadcast_peer_delete(IdxpPeer *toplist, IdxpPeer *to_delete);
 IdxpPeer *idxp_broadcast_peer_channeltype(IdxpPeer *to_change, int channel_type);
 void idxp_broadcast_send_message(int channel_type ,const char *msg);
 IdxpPeer *idxp_broadcast_peer_from_channel(IdxpPeer *toplist, IdxpChannel *channel);
 IdxpPeer *idxp_broadcast_peer_toplist(IdxpPeer *peer);

//Out of scope functions
 char *idmef_create_heartbeat(char *message_id,char *Analyzer_id,int interval,xmlNode *nodeContent,xmlNode *AddData);
#endif

